package hust.rpc.invoker;

import hust.rpc.ChannelProvider;
import hust.rpc.pojo.Channel;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.ExecutionException;

/**
 * 消费者远程服务调用类
 */
@Slf4j
public class ConsumerRemoteInvoker extends RemoteInvoker {

    /**
     * 消费者不一定持有Channel(可能只有Host信息,需要自行创建Channel连接)
     *
     * @param channel 包装的channel信息,内含Host信息,用于创建Netty Channel
     */
    @Override
    protected void handleNoChannel(Channel channel) {
        try {
            // 如果Netty Channel为空
            if (channel.getChannel() == null) {
                // 加锁同步(可能首次就多线程并发调用)
                synchronized (this) {
                    // Double check
                    if (channel.getChannel() == null) {
                        // 调用ChannelProvider连接提供者,返回Netty Channel
                        io.netty.channel.Channel internalChannel = ChannelProvider.connect(channel.getHost());
                        channel.setChannel(internalChannel);
                    }
                }
            }
        } catch (ExecutionException | InterruptedException e) {
            log.error("连接提供者" + channel.getHost() + "的连接失败", e);
            // TODO 统一异常
            throw new RuntimeException(e);
        }
    }
}
